﻿using System;
using System.Xml;
using System.Globalization;

using Joshi.Utils.Imap;

/*	-----------------------------------------------------------------------	
	Copyright:	umlungu consulting (pty) ltd
	Author:		Alan Benington
	Started:	2008-04-20
	Status:		beta
	Version:	2.0.0
	Build:		20080420
	License:	GNU General Public License
	-----------------------------------------------------------------------	*/

/*	-----------------------------------------------------------------------	
	Development Notes:
	==================
	20080420:	Started. Depends on ImapLibrary.dll by Rohit Joshi
	-----------------------------------------------------------------------	*/

namespace umlungu.engineX.emailX {
	/// <summary>
	/// umlungu EngineX x_imap class. base utility class for ImapLibrary imap object.
	/// </summary>
	/// <remarks>
	/// This class is is a wrapper to the Imap class but makes ensure disposal including logout and diconnection from the IMAP server.
	/// It also adds the accessing of default settings and values fromt the application configuration file (eg host name)
	/// </remarks>
	public class x_imap : IDisposable {
		#region Invisible properties
		private bool disposed = false;
		private Imap imap;
		private x_config config;
		#endregion

		#region Visible properties
		private string host;

		/// <summary>If user has logged in to his mailbox.</summary>
		public bool LoggedIn {
			get { return imap.m_bIsLoggedIn; }
		}
		/// <summary>Mailbox (Folder) name. Default INBOX.</summary>
		public string MailboxName {
			get { return imap.m_sMailboxName; }
		}
		/// <summary>If folder is selected.</summary>
		public bool IsFolderSelected {
			get { return imap.m_bIsFolderSelected; }
		}
		/// <summary>if folder is examined.</summary>
		public bool IsFolderExamined {
			get { return imap.m_bIsFolderExamined; }
		}
		/// <summary>Total number of messages in mailbox.</summary>
		public int TotalMessages {
			get { return imap.m_nTotalMessages; }
		}
		/// <summary>Number of recent messages in mailbox.</summary>
		public int RecentMessages {
			get { return imap.m_nRecentMessages; }
		}
		/// <summary>First unseen message UID</summary>
		public int FirstUnSeenMsgUID {
			get { return imap.m_nFirstUnSeenMsgUID; }
		}
		#endregion

		#region Constructors/Destructors
		/// <overloads>Constructor</overloads>
		/// <summary>Default constructor</summary>
		public x_imap() {
			initialise();
		}
		/// <summary>
		/// Ordinary constructor for the x_imap class.
		/// </summary>
		public x_imap(string Host) {
			host = Host;
			initialise();
		}
		/// <summary>This destructor will run only if the Dispose method does not get called.</summary>
		/// <remarks>
		/// Do not provide destructors in types derived from this class.
		/// </remarks>
		~x_imap() {
			Dispose(false);
		}
		#endregion

		#region Public methods
		/// <summary>Login to the IMAP server.</summary>
		public void Login(string Host, string User, string Pwd, bool UseSSL) {
			_Login(Host, User, Pwd, UseSSL);
		}
		/// <summary>Login to the IMAP server.</summary>
		public void Login(string User, string Pwd) {
			_Login(User, Pwd);
		}

		/// <summary>Login to the IMAP server.</summary>
		public void ExamineFolder(string User, string Pwd, string Folder) {
			_Login(User, Pwd);
			imap.ExamineFolder(Folder);
		}
		#endregion

		#region Public methods (implement IDisposable)
		/// <summary>
		/// Closes the x_imap object, by closing the connection to the database.
		/// </summary>
		public void Close() {
			Dispose();
		}
		/// <summary>
		/// Disposes the object by implementing IDisposable.
		/// </summary>
		/// <remarks>
		/// A derived class should not be able to override this method.
		/// </remarks>
		public void Dispose() {
			Dispose(true);
			// Take it off the Finalization queue to prevent finalization code for this object from executing a second time.
			GC.SuppressFinalize(this);
		}
		/// <summary>
		/// Does the disposing either from the public call, or from the destructor
		/// </summary>
		/// <remarks>
		/// A derived class may override this method in order to dispose of resources that it may create.
		/// It should call this by: base.Dispose(disposing);
		/// Dispose(bool disposing) executes in two distinct scenarios:
		/// - If disposing equals true, the method has been called directly or indirectly by a user's code. Managed and unmanaged resources can be disposed.
		/// - If disposing equals false, the method has been called by the runtime from inside the finalizer and you should not reference other objects. Only unmanaged resources can be disposed.
		/// Note that this is not thread safe.
		/// - Another thread could start disposing the object after the managed resources are disposed, but before the disposed flag is set to true.
		/// - If thread safety is necessary, it must be implemented by the client.
		/// </remarks>
		/// <param name="disposing">flag to indicate dispose in progress</param>
		protected virtual void Dispose(bool disposing) {
			// Check to see if Dispose has already been called.
			if (!this.disposed) {
				// If disposing equals true, dispose all managed and unmanaged resources.
				if (disposing) {
					// Dispose by logging out. NB Imap class handles detection of logon and disconnection
					imap.LogOut();
				}
				// Release unmanaged resources. If disposing is false, only the following code is executed.
				// eg: CloseHandle(handle);
				// eg: handle = IntPtr.Zero;
			}
			disposed = true;
		}
		#endregion

		#region Protected methods
		protected void _Login(string User, string Pwd) {
			ushort port = (ushort)Convert.ToInt16(config.ImapPort);
			_Login(config.ImapServer, port, User, Pwd, config.ImapSSL.ToLower().Equals("yes") ? true : false);
		}
		protected void _Login(string Host, string User, string Pwd) {
			_Login(Host, User, Pwd, config.ImapSSL.ToLower().Equals("yes") ? true : false);
		}
		protected void _Login(string Host, string User, string Pwd, bool UseSSL) {
			imap.Login(Host, User, Pwd, UseSSL);
		}
		protected void _Login(string Host, ushort Port, string User, string Pwd, bool UseSSL) {
			imap.Login(Host, Port, User, Pwd, UseSSL);
		}
		#endregion

		#region Private methods
		private void initialise() {
			imap = new Imap();
			config = new x_config();
		}
		#endregion
	}
}
